<!-- views/crawler/ArticlePage.vue -->
<template>
  <div class="crawler-article-page">
    <el-card class="filter-card">
      <el-form :inline="true" class="search-form" :model="searchForm" >
        <el-form-item label="数据源">
          <el-select v-model="searchForm.source" placeholder="选择数据源" style="width: 160px;" clearable>
            <el-option label="SoccerOdd" value="soccerodd" />
            <el-option label="FreeSuperTips" value="freesupertips" />
            <el-option label="ESPN" value="espn" />
          </el-select>
        </el-form-item>
        <el-form-item label="分类">
          <el-cascader
              v-model="searchForm.categoryId"
              :options="crawlerOptions"
              :props="{
        checkStrictly: true,
        label: 'name',
        value: 'id',
        emitPath: false
      }"
              placeholder="选择分类"
              clearable
              style="width: 240px;"
          >
            <template #default="{ node, data }">
              <span>{{ data.name }}</span>
              <span v-if="data.children && data.children.length">
          ({{ data.children.length }})
        </span>
            </template>
          </el-cascader>
        </el-form-item>
        <el-form-item label="关键词">
          <el-input
              v-model="searchForm.keyword"
              placeholder="搜索标题或内容"
          />
        </el-form-item>
        <el-form-item>
          <el-button type="primary" @click="handleSearch">搜索</el-button>
          <el-button @click="resetSearch">重置</el-button>
        </el-form-item>
      </el-form>
    </el-card>

    <el-card class="article-card">
      <!-- 批量操作按钮 -->
      <div class="batch-operations">
        <el-button type="primary" :disabled="!selectedArticles.length" @click="handleBatchEdit">
          批量编辑
        </el-button>
        <el-button type="danger" :disabled="!selectedArticles.length" @click="handleBatchDelete">
          批量删除
        </el-button>
        <el-button type="primary" :disabled="!selectedArticles.length" @click="handleBatchGenerate">
          批量生成视频
        </el-button>
        <el-tag v-if="selectedArticles.length" type="info">
          已选择 {{ selectedArticles.length }} 项
        </el-tag>
      </div>

      <el-table
          v-loading="loading || generatingVideo || defaultLoading"
          :data="articles?.records"
          style="width: 100%"
          @selection-change="handleSelectionChange"
      >
        <el-table-column type="selection" width="55" />
        <el-table-column prop="title" label="标题" min-width="200">
          <template #default="{ row }">
            <el-link
                type="primary"
                :href="row.url"
                target="_blank"
            >
              {{ row.title }}
            </el-link>
          </template>
        </el-table-column>
        <el-table-column prop="source" label="来源" width="120" />
        <el-table-column prop="category" label="分类" width="120" />
        <el-table-column
            prop="description"
            label="描述"
            min-width="300"
            show-overflow-tooltip
        />
        <el-table-column label="视频状态" prop="status" width="100">
          <template #default="scope">
            <el-tag :type="getVideoStatusType(scope.row.status)" v-if="scope.row.status">
              {{ scope.row.status }}
            </el-tag>
            <el-tag type="info" v-else>未生成</el-tag>
          </template>
        </el-table-column>
        <el-table-column prop="createTime" label="爬取时间" width="180" />
        <el-table-column label="操作" width="240" fixed="right">
          <template #default="{ row }">
            <el-button
                link
                type="primary"
                @click="showArticleDetail(row.id)"
            >
              查看
            </el-button>
            <el-button
                link
                type="primary"
                @click="handleEdit([row])"
                :disabled="!canGenerate(row)"
            >
              编辑
            </el-button>
            <el-button
                link
                type="primary"
                @click="handleGenerateSingle(row)"
                :disabled="!canGenerate(row)"
            >
              生成视频
            </el-button>
            <el-popconfirm
                title="确定要删除这篇文章吗？"
                @confirm="handleDelete(row.id)"
            >
              <template #reference>
                <el-button link type="danger">删除</el-button>
              </template>
            </el-popconfirm>
          </template>
        </el-table-column>
      </el-table>

      <el-empty
          v-if="!loading && articles.total === 0"
          description="暂无数据"
      >
      </el-empty>

      <div class="pagination">
        <el-pagination
            v-model:current-page="currentPage"
            v-model:page-size="pageSize"
            :total="articles?.total"
            :page-sizes="[10, 20, 50, 100]"
            layout="total, sizes, prev, pager, next"
            @size-change="handleSizeChange"
            @current-change="handleCurrentChange"
        />
      </div>
    </el-card>

    <el-dialog
        v-model="batchDeleteDialogVisible"
        title="批量删除确认"
        width="400px"
    >
      <p>确定要删除选中的 {{ selectedArticles.length }} 篇文章吗？</p>
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="batchDeleteDialogVisible = false">取消</el-button>
          <el-button type="danger" @click="confirmBatchDelete">
            确定删除
          </el-button>
        </span>
      </template>
    </el-dialog>

    <el-dialog
        v-model="batchGenerateDialogVisible"
        title="批量生成视频确认"
        width="400px"
    >
      <p>确定要为选中的 {{ selectedArticles.length }} 篇文章生成视频吗？</p>
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="batchGenerateDialogVisible = false">取消</el-button>
          <el-button type="primary" @click="confirmBatchGenerate">
            确定生成
          </el-button>
        </span>
      </template>
    </el-dialog>

    <!-- 文章详情对话框 -->
    <el-dialog
        v-model="detailDialogVisible"
        title="文章详情"
        width="800px"
    >
      <template v-if="currentArticle">
        <h2>{{ currentArticle.title }}</h2>

        <el-descriptions :column="2" border>
          <el-descriptions-item label="来源">
            {{ currentArticle.source }}
          </el-descriptions-item>
          <el-descriptions-item label="原文链接">
            <el-link
                type="primary"
                :href="currentArticle.url"
                target="_blank"
            >
              点击查看
            </el-link>
          </el-descriptions-item>
          <el-descriptions-item label="爬取时间">
            {{ currentArticle.createTime }}
          </el-descriptions-item>
          <el-descriptions-item label="视频状态">
            <el-tag :type="getVideoStatusType(currentArticle.status)">
              {{ currentArticle.status }}
            </el-tag>
          </el-descriptions-item>
          <el-descriptions-item v-if="currentArticle.videoUrl" label="视频链接">
            <el-input type="textarea" v-model="currentArticle.videoUrl" disabled>
              {{ currentArticle.videoUrl }}
            </el-input>
          </el-descriptions-item>
        </el-descriptions>
        <el-divider content-position="center">文章描述</el-divider>
        <el-input type="textarea" v-model="currentArticle.description" disabled/>
      </template>
    </el-dialog>

    <!-- 生成视频配置弹窗 -->
    <VideoConfigSelect
        v-model:visible="generateDialog.visible"
        :title="generateDialog.articles.length > 1 ? '批量生成视频配置' : '生成视频配置'"
        :default-config="defaultConfig"
        :multi-config="multiConfig"
        :default-loading="defaultLoading"
        :submitting="submitting"
        @confirm="handleGenerateConfirm"
        @close="handleGenerateClose"
    />

    <ArticleEditDialog
        v-model:visible="editDialogVisible"
        :articles="editingArticles"
        @save="handleEditSave"
    />
  </div>
</template>

<script setup>
import { ref, onMounted, reactive } from 'vue'
import { storeToRefs } from 'pinia'
import { useCrawlerStore } from '@/stores/crawler'
import { ElMessage, ElMessageBox } from 'element-plus'
import VideoConfigSelect from "@/components/VideoConfigSelect.vue";
import {useConfigStore} from "@/stores/video/config.js";
import { useTaskStore } from '@/stores/task'
import { getCategoryTree } from '@/api/category'
import ArticleEditDialog from '@/components/ArticleEditDialog.vue'
import {getMultiConfig} from "@/api/video/config.js";

const editDialogVisible = ref(false)
const editingArticles = ref([])

const configStore = useConfigStore()
const store = useCrawlerStore()
const taskStore = useTaskStore()

const generatingVideo = ref(false)  // 全局loading状态
const submitting = ref(false)       // 提交按钮loading状态

// 爬虫分类选项
const crawlerOptions = ref([])

const handleEdit = (articles) => {
  editingArticles.value = articles
  editDialogVisible.value = true
}

const handleBatchEdit = () => {
  if (selectedArticles.value.length === 0) {
    ElMessage.warning('请选择要编辑的文章')
    return
  }
  // 过滤出可编辑的文章（状态不是"已完成"和"处理中"的文章）
  const editableArticles = selectedArticles.value.filter(
      article => article.status !== '已完成' && article.status !== '处理中'
  )

  // 检查是否有可编辑的文章
  if (editableArticles.length === 0) {
    ElMessage.warning('选中的文章都是已完成或处理中状态，无法编辑')
    return
  }

  // 如果有不可编辑的文章，给用户提示
  if (editableArticles.length < selectedArticles.value.length) {
    ElMessage.info(`已过滤掉 ${selectedArticles.value.length - editableArticles.length} 篇已完成或处理中的文章`)
  }

  handleEdit(editableArticles )
}

const handleEditSave = async () => {
  await fetchArticleList()
}

// 加载爬虫分类
const loadCrawlerCategories = async () => {
  try {
    const { data } = await getCategoryTree('crawler')
    crawlerOptions.value = data
  } catch (error) {
    ElMessage.error('获取数据源分类失败')
  }
}

// 搜索表单
const searchForm = ref({
  source: '',
  keyword: '',
  categoryId: null,
})

// 生成视频相关数据
const generateDialog = reactive({
  form: {
    avatarId: '',
    voiceId: '',
    background: '#f6f6fc'
  },
  visible: false,
  articles: [] // 存储要生成视频的文章
})

// 获取默认配置
const defaultConfig = ref(null)
const multiConfig = ref(null)
const defaultLoading = ref(false)
const loadDefaultConfig = async () => {
  await configStore.getDefault()
  await configStore.getMulti()
  defaultConfig.value = configStore.defaultConfigs
  multiConfig.value = configStore.multiConfigs
}

// 分页
const currentPage = ref(1)
const pageSize = ref(10)

const selectedArticles = ref([])
const batchDeleteDialogVisible = ref(false)
const batchGenerateDialogVisible = ref(false)

// 处理表格选择变化
const handleSelectionChange = (selection) => {
  selectedArticles.value = selection
}

// 详情弹窗
const detailDialogVisible = ref(false)

// 生命周期钩子
onMounted(async () => {
  await fetchArticleList()
  await loadDefaultConfig()
  await loadCrawlerCategories()
})

const getVideoStatusType = (status) => {
  const types = {
    '未处理': 'info',
    '处理中': 'warning',
    '已完成': 'success',
    '生成失败': 'danger'
  }
  return types[status] || 'info'
}

// 判断是否可以生成视频
const canGenerate = (row) => {
  return row.status === '未处理' || row.status === '失败'
}

// 方法
const fetchArticleList = async () => {
  const params = {
    current: currentPage.value,
    size: pageSize.value,
    ...searchForm.value
  }
  await store.fetchArticles(params)
}

const handleSearch = () => {
  currentPage.value = 1
  fetchArticleList()
}

const resetSearch = () => {
  searchForm.value = {
    source: '',
    keyword: '',
    categoryId: null,
  }
  handleSearch()
}

const handleSizeChange = (val) => {
  pageSize.value = val
  fetchArticleList()
}

const handleCurrentChange = (val) => {
  currentPage.value = val
  fetchArticleList()
}

const showArticleDetail = async (id) => {
  try {
    await store.fetchArticleDetail(id)
    detailDialogVisible.value = true
  } catch (error) {
    ElMessage.error('获取文章详情失败：' + error.message)
  }
}

// 单个删除
const handleDelete = async (id) => {
  try {
    await store.deleteArticleById(id)
    ElMessage.success('删除成功')
    await fetchArticleList()
  } catch (error) {
    ElMessage.error('删除失败：' + error.message)
  }
}

// 批量删除
const handleBatchDelete = () => {
  if (selectedArticles.value.length === 0) {
    ElMessage.warning('请选择要删除的文章')
    return
  }

  // 筛选出可删除和不可删除的文章
  const deletableArticles = selectedArticles.value.filter(article => article.status === '未处理')
  const nonDeletableArticles = selectedArticles.value.filter(article => article.status !== '未处理')

  // 构建确认消息
  let confirmMessage = `确定要删除选中的 ${deletableArticles.length} 篇文章吗？`
  if (nonDeletableArticles.length > 0) {
    confirmMessage += `\n注意：其中 ${nonDeletableArticles.length} 篇已处理的文章将不会被删除。`
  }

  ElMessageBox.confirm(
      confirmMessage,
      '提示',
      {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }
  ).then(async () => {
    const ids = selectedArticles.value.map(item => item.id)
    await store.batchDeleteArticles(ids)
    await fetchArticleList()
  }).catch(() => {
    // 用户点击取消，不做任何操作
  })
}

// 处理生成视频
const handleGenerateVideo = () => {
  if (generatingVideo.value) {
    ElMessage.warning('有视频正在生成中，请稍候...')
    return
  }

  if (selectedArticles.value.length === 0) {
    ElMessage.warning('请选择要生成视频的文章')
    return
  }

  // 筛选出正在处理和已完成的文章
  const canGenerateArticles = selectedArticles.value.filter(article => article.status !== '已完成' && article.status !== '处理中')

  // 如果有不可编辑的文章，给用户提示
  if (canGenerateArticles.length < selectedArticles.value.length) {
    ElMessage.info(`已过滤掉 ${selectedArticles.value.length - canGenerateArticles.length} 篇已完成或处理中的文章`)
  }

  generateDialog.articles = canGenerateArticles
  generateDialog.visible = true
  defaultLoading.visible = true
}

// 处理单个生成
const handleGenerateSingle = (row) => {
  if (generatingVideo.value) {
    ElMessage.warning('有视频正在生成中，请稍候...')
    return
  }
  generateDialog.articles = [row]
  generateDialog.visible = true
}

const handleGenerateClose = () => {
  if (generatingVideo.value) {
    ElMessage.warning('视频正在生成中，请稍候...')
    return
  }
  generateDialog.visible = false
  generateDialog.articles = []
}

// 处理配置确认
const handleGenerateConfirm = async (config) => {
  if (generatingVideo.value) return

  try {
    submitting.value = true
    generatingVideo.value = true

    let params = {
      articleIds: generateDialog.articles.map(item => item.id),
      mode: config.mode
    }

    if (config.mode === 'single') {
      // 单数字人模式
      params.config = {
        id: config.config.id,
        avatarId: config.config.avatarId,
        voiceId: config.config.voiceId,
        xOffset: config.config.xOffset,
        yOffset: config.config.yOffset,
        scale: config.config.scale,
        backgroundType: config.config.backgroundType,
        backgroundId: config.config.backgroundId,
        backgroundColor: config.config.backgroundColor,
        backgroundUrl: config.config.backgroundUrl,
        backgroundFit: config.config.backgroundFit,
        backgroundPlayStyle: config.config.backgroundPlayStyle,
        width: config.config.width,
        height: config.config.height,
        isDefault: config.config.isDefault,
        isCaption: config.config.isCaption,
      }
    } else {
      // 多数字人模式
      params.commonConfig = {
        backgroundType: config.commonConfig.backgroundType,
        backgroundId: config.commonConfig.backgroundId,
        backgroundUrl: config.commonConfig.backgroundUrl,
        backgroundUrls: config.commonConfig.backgroundUrls,
        backgroundIds: config.commonConfig.backgroundIds,
        backgroundColor: config.commonConfig.backgroundColor,
        backgroundFit: config.commonConfig.backgroundFit,
        backgroundPlayStyle: config.commonConfig.backgroundPlayStyle,
        width: config.commonConfig.width,
        height: config.commonConfig.height,
        isCaption: config.commonConfig.isCaption,
        one_to_one: config.commonConfig.one_to_one
      }

      // 处理数字人配置列表
      params.avatarConfigs = config.avatarConfigs.map(avatar => ({
        avatarId: avatar.avatarId,
        voiceId: avatar.voiceId,
        xOffset: avatar.xOffset,
        yOffset: avatar.yOffset,
        scale: avatar.scale,
        content: avatar.content
      }))
    }

    await taskStore.generateBatchAiVideos(params)
    generateDialog.visible = false
    await fetchArticleList()
  } catch (error) {
  } finally {
    submitting.value = false
    generatingVideo.value = false
    generateDialog.visible = false
    generateDialog.articles = []
  }
}

// 批量生成视频
const handleBatchGenerate = () => {
  handleGenerateVideo()
}

// 计算属性
const { articles, loading, currentArticle } = storeToRefs(store)
</script>

<style scoped>
.crawler-article-page {
  position: relative;
  min-height: 200px;  /* 给一个最小高度以显示loading */
  padding: 20px;
}

.filter-card {
  margin-bottom: 20px;
}

.article-card {
  margin-bottom: 20px;
}

.search-form {
  margin-bottom: 20px;
}

.pagination {
  margin-top: 20px;
  text-align: right;
}

.article-content {
  max-height: 500px;
  overflow-y: auto;
  padding: 20px;
  background-color: #f5f7fa;
  border-radius: 4px;
}

:deep(.el-descriptions) {
  margin: 20px 0;
}

:deep(.el-divider__text) {
  background-color: transparent;
}

.batch-operations {
  margin-bottom: 16px;
  display: flex;
  align-items: center;
  gap: 8px;
}

.selection-count {
  margin-left: 16px;
  color: #606266;
}

.dialog-footer {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
}
</style>